package network

import (
	"fmt"
	"gitee.com/amoyx/cloud-provider/pkg/cloud/aliyun/models"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	vpc20160428 "github.com/alibabacloud-go/vpc-20160428/v6/client"
)

type VpcGreeter interface {
	VPC(region string) VpcInterface
}

type VpcInterface interface {
	Create(args models.VpcRequest) (vpcId string, err error)
	Delete(id string) (err error)
	Get(id string) (result models.VpcResponse, err error)
	ListByName(name string) (list []models.VpcResponse, err error)
	ListAll() (list []models.VpcResponse, err error)
}

type vpc struct {
	config *openapi.Config
	region string
	client *vpc20160428.Client
}

func newVpc(network *Network, region string) VpcInterface {
	v := &vpc{
		config: network.config,
		region: region,
	}
	endpoint := fmt.Sprintf("vpc.%s.aliyuncs.com", region)
	v.config.Endpoint = tea.String(endpoint)
	_client, _ := vpc20160428.NewClient(v.config)
	v.client = _client
	return v
}

// Create 创建VPC
func (v *vpc) Create(args models.VpcRequest) (vpcId string, err error) {
	var tags []*vpc20160428.CreateVpcRequestTag
	for key, val := range args.Tags {
		tags = append(tags, &vpc20160428.CreateVpcRequestTag{
			Key:   tea.String(key),
			Value: tea.String(val),
		})
	}
	createVpcRequest := &vpc20160428.CreateVpcRequest{
		RegionId:    tea.String(v.region),
		CidrBlock:   tea.String(args.CidrBlock),
		VpcName:     tea.String(args.VpcName),
		Description: tea.String(args.Description),
		Tag:         tags,
	}
	runtime := &util.RuntimeOptions{}
	response, err := v.client.CreateVpcWithOptions(createVpcRequest, runtime)
	if err != nil {
		return
	}
	vpcId = *response.Body.VpcId
	return
}

// Delete 删除VPC
func (v *vpc) Delete(id string) (err error) {
	deleteVpcRequest := &vpc20160428.DeleteVpcRequest{
		RegionId: tea.String(v.region),
		VpcId:    tea.String(id),
	}
	runtime := &util.RuntimeOptions{}
	_, err = v.client.DeleteVpcWithOptions(deleteVpcRequest, runtime)
	return
}

// Get 获取VPC
func (v *vpc) Get(id string) (result models.VpcResponse, err error) {
	list, err := v.query(id, "")
	if len(list) > 0 {
		result = list[0]
	}
	return
}

// ListByName 根据名称获取VPC列表
func (v *vpc) ListByName(name string) (list []models.VpcResponse, err error) {
	return v.query("", name)
}

// ListAll 获取VPC列表
func (v *vpc) ListAll() (list []models.VpcResponse, err error) {
	return v.query("", "")
}

func (v *vpc) query(id string, name string) (list []models.VpcResponse, err error) {
	request := &vpc20160428.DescribeVpcsRequest{
		RegionId:   tea.String(v.region),
		PageSize:   tea.Int32(50),
		PageNumber: tea.Int32(1),
	}
	if id != "" {
		request.VpcId = tea.String(id)
	}
	if name != "" {
		request.VpcName = tea.String(name)
	}
	runtime := &util.RuntimeOptions{}
	response, err := v.client.DescribeVpcsWithOptions(request, runtime)
	if err != nil {
		return
	}
	for _, row := range response.Body.Vpcs.Vpc {
		tags := make(map[string]string)
		for _, tag := range row.Tags.Tag {
			tags[*tag.Key] = *tag.Value
		}
		var gatewayIds []string
		for _, gw := range row.NatGatewayIds.NatGatewayIds {
			gatewayIds = append(gatewayIds, *gw)
		}
		var switchIds []string
		for _, sw := range row.VSwitchIds.VSwitchId {
			switchIds = append(switchIds, *sw)
		}
		var routeIds []string
		for _, rt := range row.RouterTableIds.RouterTableIds {
			routeIds = append(routeIds, *rt)
		}
		list = append(list, models.VpcResponse{
			VpcId:          *row.VpcId,
			VpcName:        *row.VpcName,
			CidrBlock:      *row.CidrBlock,
			Status:         *row.Status,
			CreationTime:   *row.CreationTime,
			RegionId:       *row.RegionId,
			Description:    *row.Description,
			IsDefault:      *row.IsDefault,
			Tags:           tags,
			VSwitchIds:     switchIds,
			NatGatewayIds:  gatewayIds,
			RouterTableIds: routeIds,
		})
	}
	return
}
